/*
 *Copyright (c) 2024 Black Sesame Technologies
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
*/

#ifndef _IPC_HW_COMMON_H
#define _IPC_HW_COMMON_H

#include "bst_ipc_config.h"
#include "ipc_hw_config.h"
// msgbx end init  ------------------------------------------------------------------------
// safety management enable flag bit
#define MSGBX_ECC_RX_MULTIP_EN_BIT 0x08
#define MSGBX_ECC_RX_DETECT_EN_BIT 0x04
#define MSGBX_PARITY_HWDATA_EN_BIT 0x02
#define MSGBX_PARITY_HADDR_EN_BIT 0x01

enum _ipc_hw_device_type_t {
	IPC_HW_MSGBX_MODE = 0,
	IPC_HW_INT_MODE = 1,
	IPC_HW_SEM_MODE = 2,
	IPC_HW_MAX_MODE
};
#define ipc_hw_device_type_t enum _ipc_hw_device_type_t

enum _ipc_type_t {
	MSGBX_ROLE_CLIENT_ONLY = 1,
	MSGBX_ROLE_SERVER_ONLY = 2,
	MSGBX_ROLE_HYBRID = 3,
	MSGBX_ROLE_TYPE_MAX
};
#define ipc_type_t enum _ipc_type_t

/**
 * ipc_init_params: ipc hardware device static init param
 * @mbx_device:
 * @mbx_role:
 * @msgbx_end_mgt_flag:
 */
struct _ipc_init_params_t {
	// static device setting
	ipc_hw_device_type_t mbx_device;
	ipc_type_t mbx_type;
	// special device setting
	uint64_t spec_cfg;
	// optional device setting
	// state management setting
	uint8_t msgbx_end_mgt_flag;
};
#define ipc_init_params_t struct _ipc_init_params_t

struct _msgbx_hw_info_t {
	uint8_t mbx_version : 4; // RO, version checking
	uint8_t mbx_flt_cnt : 4; // RO, flt checking
	uint8_t mbx_end_id : 8; // RO, for msg header
	uint8_t mbx_txfifo_depth : 8; // RO
	uint8_t mbx_rxfifo_depth : 8; // RO
	uint8_t is_64_bit; // RO, reserved
};
#define msgbx_hw_info_t struct _msgbx_hw_info_t

// msgbx filter management  ------------------------------------------------------------------------
// msgbx filter config
struct _msgbx_flt_cfg_t {
	uint8_t flt_id;
	// optional setting, msgbx filter general config, use bit offset refer to different config
	uint8_t mbx_flt_mgt_flag;
};
#define msgbx_flt_cfg_t struct _msgbx_flt_cfg_t

enum _ipc_flt_rule_typ_t {
	IPC_FLT_RULE_PID = 1,
	IPC_FLT_RULE_LEN = 2,
	IPC_FLT_RULE_USER = 3,
	IPC_FLT_RULE_MAX,
};
#define ipc_flt_rule_typ_t enum _ipc_flt_rule_typ_t

struct _ipc_flt_rule_type_t {
	uint16_t mbx_rx_pid_end : 8; // RW
	uint16_t mbx_rx_pid_st : 8; // RW
	uint8_t mbx_pid_flt_invert : 1; // RW
};
#define ipc_flt_rule_type_t struct _ipc_flt_rule_type_t

struct _msgbx_flt_rule_len_t {
	uint8_t mbx_len_flt_invert : 1;
	uint8_t mbx_rx_len_end : 4;
	uint8_t mbx_rx_len_st : 4;
};
#define msgbx_flt_rule_len_t struct _msgbx_flt_rule_len_t

enum _ipc_flt_rule_location_t {
	IPC_FLT_RULE_HEADER = 1,
	IPC_FLT_RULE_PAY1 = 2,
	IPC_FLT_RULE_PAY2 = 3,
	IPC_FLT_RULE_PAY3 = 4,
	IPC_FLT_RULE_PAY4 = 5,
	IPC_FLT_RULE_PAY_MAX,
};
#define ipc_flt_rule_location_t enum _ipc_flt_rule_location_t

struct _msgbx_flt_rule_user_t {
	ipc_flt_rule_location_t cfg_loc;
	uint32_t msgh_combi_lh_comp; // default is enable
	uint32_t msgh_flilter_invert; // default is disable
	uint64_t tx_reserved_filter_mask : 64;
	uint64_t rx_res_min : 64;
	uint64_t rx_res_max : 64;
};
#define msgbx_flt_rule_user_t struct _msgbx_flt_rule_user_t

struct _msgbx_flt_rule_cfg_t {
	ipc_flt_rule_typ_t cfg_type;
	union {
		ipc_flt_rule_type_t rule_pid;
		msgbx_flt_rule_len_t rule_len;
		msgbx_flt_rule_user_t rule_user;
	};
};
#define msgbx_flt_rule_cfg_t struct _msgbx_flt_rule_cfg_t

// msgbx state management ------------------------------------------------------------------------
// state management enable flag bit
#define MSGBX_TX_OVERFLOW_EN_BIT 0x04 // only available for msgbx default filter
#define MSGBX_RX_OVERFLOW_EN_BIT 0x02
#define MSGBX_RX_UNDERFLOW_EN_BIT 0x01

enum _ipc_err_msg_typ_t {
	IPC_MSB_END_ERR_TYP = 1,
	IPC_MSB_FIL_ERR_TYP = 2, // default filter err & config filter err
	IPC_ERR_TYP_MAX
};
#define ipc_err_msg_typ_t enum _ipc_err_msg_typ_t

struct _msgbx_flt_info_t {
	uint32_t mbx_rxfifo_end_addr : 10; // RW, this info is got from hw impl
	uint32_t mbx_rxfifo_st_addr : 10; // RW
};
#define msgbx_flt_info_t struct _msgbx_flt_info_t

struct _msgbx_flt_device_t {
	msgbx_flt_cfg_t cfg;
	msgbx_flt_info_t info;
	msgbx_flt_rule_cfg_t rule;
};
#define msgbx_flt_device_t struct _msgbx_flt_device_t

// msgbx device
struct _msgbx_hw_device_t {
	ipc_hw_device_type_t hw_type;
	msgbx_hw_info_t hw_cfg;
	uint64_t spec_cfg;
};
#define msgbx_hw_device_t struct _msgbx_hw_device_t

// msgbx error msg
struct _msgbx_err_msg_t {
	uint8_t type : 4; // msgbx. msgend, msgflt
	uint8_t id : 4;
	uint8_t msg : 8; // overflow, underflow, threshold
	uint64_t res : 16;
};
#define msgbx_err_msg_t struct _msgbx_err_msg_t
// maybe it has big-endian or little-endian issue

#endif
